package model

import (
	"Short_chain_cats/database"
	"context"
	"fmt"
	"strings"
	"time"

	"gorm.io/gorm"
)

var LinksModel = Links{}

type Links struct {
	Id            int64     `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT;NOT NULL"`
	Title         string    `json:"title" gorm:"column:title;default:NULL;comment:'链接标题'"`
	UrlImg        string    `json:"urlImg" gorm:"column:urlImg;default:NULL;comment:'链接图标'"`
	Tags          string    `json:"tags" gorm:"column:tags;default:NULL;comment:'标签列表（json 数组）'"`
	LongUrl       string    `json:"longUrl" gorm:"column:longUrl;comment:'长链'"`
	SortUrl       string    `json:"sortUrl" gorm:"column:sortUrl;default:NULL;comment:'短链'"`
	UserId        int       `json:"userId" gorm:"column:userId;NOT NULL;comment:'创建用户 id'"`
	Visits        int32     `json:"visits" gorm:"column:visits;default:0;NOT NULL;comment:'访问次数'"`
	IpNums        int32     `json:"ipNums" gorm:"column:ipNums;default:0;NOT NULL;comment:'ip数'"`
	UserNums      int32     `json:"userNums" gorm:"column:userNums;default:0;NOT NULL;comment:'访问数'"`
	AllowNum      int32     `json:"allowNum" gorm:"column:allowNum;default:0;NOT NULL;comment:'允许访问次数'"`
	PrivateTarget int8      `json:"privateTarget" gorm:"column:privateTarget;default:0;NOT NULL;comment:'是否私密'"` //1为不私密2为私密
	Password      string    `json:"password" gorm:"column:password;default:NULL;comment:'密码'"`
	ExpireTime    time.Time `json:"expireTime" gorm:"column:expireTime;default:NULL;comment:'过期时间'"`
	Status        int8      `json:"status" gorm:"column:status;default:0;NOT NULL;comment:'状态：0 草稿 1 发布 2 禁用'"`
	CreateTime    time.Time `json:"createTime" gorm:"column:createTime;default:CURRENT_TIMESTAMP;NOT NULL;comment:'创建时间'"`
	UpdateTime    time.Time `json:"updateTime" gorm:"column:updateTime;default:CURRENT_TIMESTAMP;NOT NULL;comment:'更新时间'"`
	IsDelete      int8      `json:"isDelete" gorm:"column:isDelete;default:0;NOT NULL;comment:'是否删除'"`
}

func (Links) TableName() string {
	return "url_relate"
}

type GenerateLinksReq struct {
	LongUrl string `json:"longUrl" gorm:"column:longUrl;comment:'长链'"`
	UserId  int    `json:"userId" gorm:"column:userId;NOT NULL;comment:'创建用户 id'"`
}

func (q *GenerateLinksReq) GenerateLinksResponse(r *GenerateLinksResp) {
	r.LongUrl = q.LongUrl
	r.UserId = q.UserId
	r.PrivateTarget = 2
	r.ExpireTime = time.Date(9999, time.January, 1, 0, 0, 0, 0, time.UTC)
	//ExpireTime : time.Now().Add(15 * time.Minute),
}

type GenerateLinksResp struct {
	Title         string    `json:"title" gorm:"column:title;default:NULL;comment:'链接标题'"`
	UrlImg        string    `json:"url_img" gorm:"column:urlImg;default:NULL;comment:'链接图标'"`
	Tags          string    `json:"tags" gorm:"column:tags;default:NULL;comment:'标签列表（json 数组）'"`
	LongUrl       string    `json:"longUrl" gorm:"column:longUrl;comment:'长链'"`
	SortUrl       string    `json:"sortUrl" gorm:"column:sortUrl;default:NULL;comment:'短链'"`
	UserId        int       `json:"userId" gorm:"column:userId;NOT NULL;comment:'创建用户 id'"`
	Visits        int32     `json:"visits" gorm:"column:visits;default:0;NOT NULL;comment:'访问次数'"`
	IpNums        int32     `json:"ipNums" gorm:"column:ipNums;default:0;NOT NULL;comment:'ip数'"`
	UserNums      int32     `json:"userNums" gorm:"column:userNums;default:0;NOT NULL;comment:'访问数'"`
	AllowNum      int32     `json:"allowNum" gorm:"column:allowNum;default:0;NOT NULL;comment:'允许访问次数'"`
	PrivateTarget int8      `json:"privateTarget" gorm:"column:privateTarget;default:0;NOT NULL;comment:'是否私密'"` //1为不私密2为私密
	ExpireTime    time.Time `json:"expireTime" gorm:"column:expireTime;default:NULL;comment:'过期时间'"`
	Status        int8      `json:"status" gorm:"column:status;default:0;NOT NULL;comment:'状态：0 草稿 1 发布 2 下架'"`
	Len           int8
}

func (q *GenerateLinksResp) GenerateLinks(r *Links) {
	r.Tags = q.Tags
	r.Title = q.Title
	r.UrlImg = q.UrlImg
	r.LongUrl = q.LongUrl
	r.SortUrl = q.SortUrl
	r.UserId = q.UserId
	r.Visits = q.Visits
	r.IpNums = q.IpNums
	r.UserNums = q.UserNums
	r.AllowNum = q.AllowNum
	r.PrivateTarget = q.PrivateTarget
	r.ExpireTime = q.ExpireTime
	r.Status = q.Status
	r.CreateTime = time.Now()
	r.UpdateTime = time.Now()
}

// ReviseLinksReq 发布短链请求参数
type ReviseLinksReq struct {
	Id            int64     `json:"id" gorm:"column:id;primary_key;AUTO_INCREMENT;NOT NULL"`
	UserId        int       `json:"userId" gorm:"column:userId;NOT NULL;comment:'创建用户 id'"`
	Title         string    `json:"title" gorm:"column:title;default:NULL;comment:'链接标题'"`
	UrlImg        string    `json:"urlImg" gorm:"column:urlImg;default:NULL;comment:'链接图标'"`
	Tags          []int     `json:"tags" gorm:"column:tags;default:NULL;comment:'标签列表（json 数组）'"`
	LongUrl       string    `json:"longUrl" gorm:"column:longUrl;comment:'长链'"`
	SortUrl       string    `json:"sortUrl" gorm:"column:sortUrl;default:NULL;comment:'短链'"`
	Visits        int32     `json:"visits" gorm:"column:visits;default:0;NOT NULL;comment:'访问次数'"`
	IpNums        int32     `json:"ipNums" gorm:"column:ipNums;default:0;NOT NULL;comment:'ip数'"`
	UserNums      int32     `json:"userNums" gorm:"column:userNums;default:0;NOT NULL;comment:'访问数'"`
	AllowNum      int32     `json:"allowNum" gorm:"column:allowNum;default:0;NOT NULL;comment:'允许访问次数'"`
	PrivateTarget int8      `json:"privateTarget" gorm:"column:privateTarget;default:0;NOT NULL;comment:'是否私密'"` //1为不私密2为私密
	Password      string    `json:"password" gorm:"column:password;default:NULL;comment:'密码'"`
	Status        int8      `json:"status" gorm:"column:status;default:0;NOT NULL;comment:'状态：0 草稿 1 发布 2 下架'"`
	UpdateTime    time.Time `json:"updateTime" gorm:"column:updateTime;default:CURRENT_TIMESTAMP;NOT NULL;comment:'更新时间'"`
	ExpireTime    time.Time `json:"expireTime" gorm:"column:expireTime;default:NULL;comment:'过期时间'"`
	Len           int8
}

func (q *ReviseLinksReq) GenerateLinksReq(r *Links) {
	r.Id = q.Id
	r.Title = q.Title
	r.UrlImg = q.UrlImg
	//r.Tags = q.Tags
	r.LongUrl = q.LongUrl
	r.SortUrl = q.SortUrl
	r.Visits = q.Visits
	r.IpNums = q.IpNums
	r.UserNums = q.UserNums
	r.AllowNum = q.AllowNum
	r.PrivateTarget = q.PrivateTarget
	r.Password = q.Password
	r.Status = q.Status
	r.UpdateTime = time.Now()
	r.ExpireTime = q.ExpireTime
}

type ViewLinksReq struct {
	UserId   int64 `json:"userId" gorm:"column:userId;NOT NULL;comment:'创建用户 id'"`
	Page     int   `json:"page" form:"page"`
	PageSize int   `json:"pageSize" form:"pageSize"`
}

type EditLinksReq struct {
	Id            int64  `json:"id"`
	UserId        int    `json:"userId"`
	Title         string `json:"title"`
	Tags          []int  `json:"tags"`
	PrivateTarget int8   `json:"privateTarget"` //1为不私密2为私密
	Password      string `json:"password" `
	Status        int8   `json:"status"`
}

type EditLinksModel struct {
	Id            int64  `json:"id" gorm:"column:id"`
	UserId        int    `json:"userId" gorm:"column:userId"`
	Title         string `json:"title" gorm:"column:title"`
	Tags          string `json:"tags" gorm:"column:tags"`
	PrivateTarget int8   `json:"privateTarget" gorm:"column:privateTarget"` //1为不私密2为私密
	Password      string `json:"password"  gorm:"column:password"`
	Status        int8   `json:"status" gorm:"column:status"`
}

func (q *EditLinksReq) GenerateEditLinksReq(r *EditLinksModel) {
	r.Id = q.Id
	r.UserId = q.UserId
	r.Title = q.Title
	r.PrivateTarget = q.PrivateTarget
	r.Password = q.Password
	r.Status = q.Status
}

type ViewLinksMid struct {
	Id            int64  `json:"id"`
	Title         string `json:"title"`
	UrlImg        string `json:"urlImg"`
	LongUrl       string `json:"longUrl"`
	SortUrl       string `json:"sortUrl"`
	UserId        int    `json:"userId"`
	Visits        int32  `json:"visits"`
	IpNums        int32  `json:"ipNums"`
	UserNums      int32  `json:"userNums"`
	AllowNum      int32  `json:"allowNum"`
	PrivateTarget int8   `json:"privateTarget"` //1为不私密2为私密
	Status        int8   `json:"status"`
	Tags          []UrlTag
}

func (q Links) GenerateViewLinksResp(r *ViewLinksMid) {
	r.Id = q.Id
	r.Title = q.Title
	r.UrlImg = q.UrlImg
	r.LongUrl = q.LongUrl
	r.SortUrl = q.SortUrl
	r.UserId = q.UserId
	r.Visits = q.Visits
	r.IpNums = q.IpNums
	r.UserNums = q.UserNums
	r.AllowNum = q.AllowNum
	r.PrivateTarget = q.PrivateTarget
	r.Status = q.Status
}

type ViewLinksResp struct {
	List  []ViewLinksMid `json:"list"`
	Total int64          `json:"total"`
}

func (Links) CheckLinks(ctx context.Context, longUrl string) (*Links, error) {
	var resp Links

	err := database.NewOrm(ctx).Where("longUrl = ? AND isDelete = ? ", longUrl, 0).First(&resp).Error
	if err != nil {
		if err.Error() == gorm.ErrRecordNotFound.Error() {
			return nil, nil
		}
		return nil, err
	}
	return &resp, nil
}

func (Links) Create(ctx context.Context, linksStor *GenerateLinksResp) (*Links, error) {
	var links Links
	linksStor.GenerateLinks(&links)

	err := database.NewOrm(ctx).Create(&links).Error
	if err != nil {
		return nil, err
	}
	return &links, nil
}

func (Links) ViewLinks(ctx context.Context, req ViewLinksReq) (*ViewLinksResp, error) {
	var resp []Links
	var links ViewLinksMid
	var result []ViewLinksMid
	var res ViewLinksResp
	var maps map[string]UrlTag
	var ids []string
	var count int64
	err := database.NewOrm(ctx).Where("userId = ? AND isDelete = ?", req.UserId, 0).Offset(req.Page * req.PageSize).
		Limit(req.PageSize).Find(&resp).Error
	if err != nil {
		return nil, err
	}
	if len(resp) == 0 {
		return nil, nil
	}
	//处理参数
	//拿到映射的map
	maps, err = TagsModel.TagMap(ctx)
	if err != nil {
		return nil, err
	}
	//首先遍历切片中的每一个数
	for _, i := range resp {
		i.GenerateViewLinksResp(&links)
		if i.Tags != "" {
			flag := false
			for n := 0; n < len(i.Tags); n++ {
				if i.Tags[n] == '#' {
					flag = true
				}
			}
			if flag {
				ids = strings.Split(i.Tags, "#")
			} else {
				ids = append(ids, i.Tags)
			}

			//遍历切片中每一个数，通过映射后添加到links.Tage中
			for _, v := range ids {
				if structs, ok := maps[v]; ok {
					links.Tags = append(links.Tags, structs)
				} else {
					return nil, err
				}
			}
		}

		result = append(result, links)
	}
	//获取总数
	err = database.NewOrm(ctx).Table("url_relate").Where("userId = ? AND isDelete = ?", req.UserId, 0).Count(&count).Error
	if err != nil {
		return nil, err
	}
	res.List = result
	res.Total = count
	return &res, nil
}

func (Links) VisitLinks(ctx context.Context, shortUrl string) (*ViewLinksMid, error) {
	var resp Links
	var res ViewLinksMid
	var maps map[string]UrlTag
	var ids []string
	err := database.NewOrm(ctx).Where("sortUrl = ? AND isDelete = ?", shortUrl, 0).First(&resp).Error
	if err != nil {
		if err.Error() == gorm.ErrRecordNotFound.Error() {
			fmt.Println("未查找到数据~")
			return nil, nil
		}
		return nil, err
	}
	//处理返回参数
	//拿到映射的map
	maps, err = TagsModel.TagMap(ctx)
	if err != nil {
		return nil, err
	}
	resp.GenerateViewLinksResp(&res)
	if resp.Tags != "" {
		flag := false
		for n := 0; n < len(resp.Tags); n++ {
			if resp.Tags[n] == '#' {
				flag = true
			}
		}
		if flag {
			ids = strings.Split(resp.Tags, "#")
		} else {
			ids = append(ids, resp.Tags)
		}

		//遍历切片中每一个数，通过映射后添加到links.Tage中
		for _, v := range ids {
			if structs, ok := maps[v]; ok {
				res.Tags = append(res.Tags, structs)
			} else {
				return nil, err
			}
		}
	}

	return &res, nil
}

func (Links) FindLinks(ctx context.Context, id int64) (*Links, error) {
	var resp Links

	err := database.NewOrm(ctx).Where("id = ? AND isDelete = ?", id, 0).First(&resp).Error
	if err != nil {
		if err.Error() == gorm.ErrRecordNotFound.Error() {
			return nil, nil
		}
		return nil, err
	}
	return &resp, nil
}

func (Links) UpdateLinks(ctx context.Context, id int64) error {

	err := database.NewOrm(ctx).Table("url_relate").Where("id = ? AND isDelete = ?", id, 0).Update("isDelete", 1).Error
	if err != nil {
		return err
	}
	return nil
}

func (Links) PublishLinks(ctx context.Context, links *Links) (*ViewLinksMid, error) {
	var res ViewLinksMid
	var maps map[string]UrlTag
	var ids []string
	err := database.NewOrm(ctx).Where("id = ? AND isDelete = ?", links.Id, 0).Save(&links).Error
	if err != nil {
		return nil, err
	}
	//处理返回参数
	//拿到映射的map
	maps, err = TagsModel.TagMap(ctx)
	if err != nil {
		return nil, err
	}
	links.GenerateViewLinksResp(&res)
	if links.Tags != "" {
		flag := false
		for n := 0; n < len(links.Tags); n++ {
			if links.Tags[n] == '#' {
				flag = true
			}
		}
		if flag {
			ids = strings.Split(links.Tags, "#")
		} else {
			ids = append(ids, links.Tags)
		}

		//遍历切片中每一个数，通过映射后添加到links.Tage中
		for _, v := range ids {
			if structs, ok := maps[v]; ok {
				res.Tags = append(res.Tags, structs)
			} else {
				return nil, err
			}
		}
	}

	return &res, nil
}

func (Links) EditLinks(ctx context.Context, links *EditLinksModel) error {
	err := database.NewOrm(ctx).Table("url_relate").Select("*").Updates(&links).Error
	if err != nil {
		return err
	}
	return nil
}
